package com.test.A05;

import java.io.IOException;
import java.util.Set;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;

public class AtBeanPostProcessor implements BeanFactoryPostProcessor{

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
		 try {
	            CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
	            MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/test/A05/Config.class"));
	            Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
	            for (MethodMetadata method : methods) {
	                System.out.println(method);
	                String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
	                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
	                builder.setFactoryMethodOnBean(method.getMethodName(), "config");
	                builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
	                if (initMethod.length() > 0) {
	                    builder.setInitMethodName(initMethod);
	                }
	                AbstractBeanDefinition bd = builder.getBeanDefinition();
	                if(configurableListableBeanFactory instanceof DefaultListableBeanFactory) {
	                	DefaultListableBeanFactory  beanFactory =(DefaultListableBeanFactory)configurableListableBeanFactory;
	                	 beanFactory.registerBeanDefinition(method.getMethodName(), bd);
	                }
	               
	            }
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	}

}
